package com.hzdesk.media.koreabatchmatvector.service;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.media.ThumbnailUtils;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.hzdesk.media.koreabatchmatvector.R;
import com.hzdesk.media.koreabatchmatvector.base.MyClientApplication;
import com.hzdesk.media.koreabatchmatvector.bean.Memory;
import com.hzdesk.media.koreabatchmatvector.bean.VideoFile;
import com.hzdesk.media.koreabatchmatvector.bean.XmlMeetingBean;
import com.hzdesk.media.koreabatchmatvector.bean.XmlUserBean;
import com.hzdesk.media.koreabatchmatvector.bean.XmlVideoFile;
import com.hzdesk.media.koreabatchmatvector.config.AppConfig;
import com.hzdesk.media.koreabatchmatvector.config.RxBusUtil;
import com.hzdesk.media.koreabatchmatvector.dao.MemoryDaoUtils;
import com.hzdesk.media.koreabatchmatvector.dao.MouseUserDevicesinfoDaoUtils;
import com.hzdesk.media.koreabatchmatvector.dao.VideoFileDaoUtils;
import com.hzdesk.media.koreabatchmatvector.matvector.HDMIRxPlayer;
import com.hzdesk.media.koreabatchmatvector.utils.FileUtil;
import com.hzdesk.media.koreabatchmatvector.utils.MyToastUtils;
import com.hzdesk.media.koreabatchmatvector.utils.RxBus;
import com.hzdesk.media.koreabatchmatvector.utils.SharedPreferencesUtils;
import com.hzdesk.media.koreabatchmatvector.utils.XMLUtil;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import okhttp3.FormBody;

/**
 * Created by Administrator on 2018/6/23.
 * 杭州席媒科技有限公司  Developers  刘传华  09
 * 佛祖镇楼 bug辟易
 * 存储目录-------------
 * ----------Deskmedia
 * -------------会议1
 * -----------------会议1-1
 * -----------------会议1-1.mp4
 * -----------------会议1-1.xml
 * -----------------会议1-1.jpg
 * -----------------会议1-1.png
 * -----------------会议1-1.awr
 * -------------会议1-2
 */

public class RecordService extends Service {
    private static String TAG = "RecordService";
    private RecordBind myRecordBind = new RecordBind();
    private String meetingname, suffixName;
    private HDMIRxPlayer m_HDMIRxPlayer = null;
    private boolean isRecording = false;            //录制控制 true 已经在录制 false 停止录制
    private boolean isStopRecord=false;             //停止录制
    private long startTime;

    private int BitmapCompressWidth = 800;            //图片压缩宽度
    private int BitmapCompressHight = 480;            //图片压缩高度

    private String myUUID;

    private List<XmlVideoFile> xmlVideoFileList;        //xml文件的file集合
    private List<Long> startTimeList;                   //开始时间点
    private List<Long> stopTimeList;                    //停止时间点
    private List<VideoFile> videoFileList;              //videoFile集合
    private List<XmlUserBean> xmlUserBeanList;
    private String XmlPath;                             //xml文件最初保存路径
    private Context context;

    private MediaRecorder mMediaRecorder;

    private String meetingdirpath;                       //会议路径           /Deskmedia/会议1
    private String dirpath;                              //保存文件的文件夹路径 /Deskmedia/会议1/会议1-1

    private String realname;                               //第二名称


    private int i = 1;
    private int j = 1;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return myRecordBind;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        xmlVideoFileList = new ArrayList<>();
        startTimeList = new ArrayList<>();
        stopTimeList = new ArrayList<>();
        videoFileList = new ArrayList<>();
        MouseUserDevicesinfoDaoUtils mouseUserDevicesinfoDaoUtils = new MouseUserDevicesinfoDaoUtils(this);
        xmlUserBeanList = mouseUserDevicesinfoDaoUtils.queryUserInfo();
        getFileSuffix();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    public void setHDMIRxPlayer(HDMIRxPlayer hDMIRxPlayer) {
        m_HDMIRxPlayer = hDMIRxPlayer;
    }

    /**
     * 开始录制
     */
    public void startRecord(Context mContext, boolean isFirst) {
        if (MyClientApplication.isRecording()) {
            showToast(R.string.recording);

        } else if (getSurplusSize()) {
            context = mContext;
            if (isFirst) {
                MyClientApplication.setStartTime(new Date().getTime());
                startTimeList.add(0L);
                myUUID = getMyUUID();
                //更新文件名称
                j = 1;
                suffixName = i + "-" + j;
                //会议1
                meetingname = getMeetingname(mContext) + i;
                j++;
                ;
                Log.e(TAG, "new  meetingName:" + suffixName);
            } else {
                startTimeList.add(getCurrentTime() - MyClientApplication.getStartTime());
                suffixName = i + "-" + j;
                Log.e(TAG, "subsection meetingName:" + suffixName);
                j++;
            }
            realname = FileUtil.setFileName();
            //开启分段线程
            MyClientApplication.setIsRecording(true);
            new SubSectionThread().start();
            fileisExit(mContext);
            //保存开始时间

            showToast(R.string.start_record);

            meetingdirpath = getStoragePath(mContext) + "/" + meetingname;
            Log.d(TAG, meetingdirpath);

            dirpath = meetingdirpath + "/" + getFilename(mContext);
            Log.d(TAG, dirpath);
            //视频文件路径       /Deskmedia/会议1/会议1-1/会议1-1.mp4
            String videopath = dirpath + "/" + getFilename(mContext) + AppConfig.FILE_TYPE_MP4;
            Log.d(TAG, videopath);
            //音频文件路径       /Deskmedia/会议1/会议1-1/会议1-1.awr
            String awrpath = dirpath + "/" + getFilename(mContext) + AppConfig.FILE_TYPE_AMR;
            Log.d(TAG, awrpath);
            //创建文件夹
            FileUtil.createDir(new File(meetingdirpath));
            FileUtil.createDir(new File(dirpath));
            //创建会议描述文件
            createMeetingXml();
            //创建视频文件
            File file = new File(videopath);
            FileUtil.createNewFile(file);
            //录制音频
            if (SharedPreferencesUtils.getRecordMode(mContext) == 1) {
                createMediaRecord(awrpath);
            }
            //录制视频
            int mode = ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE;
            try {
                ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, mode);
                m_HDMIRxPlayer.startRecord(pfd);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, R.string.capacity_warning, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 停止录制
     */
    public void stopRecord(Context mContext, boolean isSubSection) {
        if (MyClientApplication.isRecording()) {
            MyClientApplication.setIsRecording(false);
            //停止录制音频
            closeMediaRecord();
            //停止录制
            m_HDMIRxPlayer.stopRecord();
            //保存结束时间
            stopTimeList.add(getCurrentTime() - MyClientApplication.getStartTime());

            String name = getFilename(mContext);
            getFragemAtTime(mContext);
            try {
                long size = FileUtil.getFileSize(new File(dirpath));
                videoFileList.add((new VideoFile(null, name, new File(name + AppConfig.FILE_TYPE_MP4).lastModified(), getStoragePath(mContext), size, realname, myUUID, meetingname, MyClientApplication.getStartTime())));
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (isSubSection) {
                //开始录制
                startRecord(mContext, false);
            } else {
                //会议名称+1
                i++;
                isStopRecord=true;
                //生成xml文件
                for (int i = 0; i < videoFileList.size(); i++) {
                    xmlVideoFileList.add(new XmlVideoFile(videoFileList.get(i).getName(), videoFileList.get(i).getSecondname(), startTimeList.get(i), stopTimeList.get(i)));
                }
                XmlPath = dirpath + "/" + getFilename(mContext) + AppConfig.FILE_TYPE_XML;
                XMLUtil.CreatXMLFile(MyClientApplication.getmPathBeanList(), xmlVideoFileList, xmlUserBeanList, XmlPath, getCurrentTime() - MyClientApplication.getStartTime());
                Iterator<?> it = MyClientApplication.getmPathBeanList().iterator();
                while (it.hasNext()) {
                    it.next();
                    it.remove();
                }
                showLoadDialog();
                saveXmlFile();
                showToast(R.string.stop_record);
            }


        }

    }

    /**
     * 开始音频录制
     */
    private void createMediaRecord(String path) {
        try {
         /* ①Initial：实例化MediaRecorder对象 */
            mMediaRecorder = new MediaRecorder();

        /* setAudioSource/setVedioSource*/
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置麦克风

        /* 设置输出文件的格式：THREE_GPP/MPEG-4/RAW_AMR/Default
         * THREE_GPP(3gp格式，H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
         */
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

         /* 设置音频文件的编码：AAC/AMR_NB/AMR_MB/Default */
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

         /* 设置输出文件的路径 */
            File file = new File(path);
            if (file.exists()) {
                file.delete();
            }
            mMediaRecorder.setOutputFile(path);

            mMediaRecorder.prepare();
            mMediaRecorder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止音频录制
     */
    private void closeMediaRecord() {
        if (mMediaRecorder != null) {
            mMediaRecorder.stop();
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
    }

    /**
     * 获取视频第一帧
     *
     * @param mContext
     */
    @SuppressLint("StaticFieldLeak")
    private void getFragemAtTime(Context mContext) {
        //视频文件路径         /Deskmedia/会议1/会议1-1/会议1-1.mp4
        String videopath = dirpath + "/" + getFilename(mContext) + AppConfig.FILE_TYPE_MP4;

        //缩略图文件路径       /Deskmedia/会议1/会议1-1/会议1-1.jgp
        String jpgpath = dirpath + "/" + getFilename(mContext) + AppConfig.FILE_TYPE_JPG;
        Log.d(TAG, jpgpath);

        if (FileUtil.isFileExist(videopath)) {
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    Bitmap bitmap = null;
                    MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
                    File videofile=new File(videopath);
                    mediaMetadataRetriever.setDataSource(videofile.getAbsolutePath());
                    bitmap = mediaMetadataRetriever.getFrameAtTime();
                    bitmap = ThumbnailUtils.extractThumbnail(bitmap, BitmapCompressWidth, BitmapCompressHight, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
                    if (bitmap != null) {
                        File file = new File(jpgpath);
                        try {
                            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bos);
                            bos.flush();
                            bos.close();
                            mediaMetadataRetriever.release();
                            Log.e(TAG, "getFragemAtTime success");
                            dismissLoadDialog();
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else {
                        Log.e(TAG, "getFragemAtTime fail");
                    }
                }
            }.start();

        }

    }

    /**
     * 生成会议信息文件 /Deskmedia/会议1/会议1.xml
     */
    private void createMeetingXml() {
        XmlMeetingBean xmlMeetingBean=new XmlMeetingBean(MyClientApplication.getStartTime(),meetingname);
        //  /Deskmedia/会议1/会议1.xml
        String path=meetingdirpath+"/"+meetingname+AppConfig.FILE_TYPE_XML;
        XMLUtil.CreatMeetingXml(xmlMeetingBean,path);


    }


    /**
     * 把文件复制到所有文件夹下（xml文件保存在最后录制的一段视频文件目录下，所以需要把xml文件复制到其他段的视频目录下）
     */
    private void saveXmlFile() {
        Log.e(TAG, "saveXmlFile--------");
        for (int i = 0; i < videoFileList.size(); i++) {


            //水印文件路径       /Deskmedia/会议1/会议1-1/会议1-1.png
            String pngPath = videoFileList.get(i).getPath() + "/" + videoFileList.get(i).getMeetingName() + "/" + videoFileList.get(i).getName() +"/" + videoFileList.get(i).getName() +  AppConfig.FILE_TYPE_PNG;

            //批注文件路径       /Deskmedia/会议1/会议1-1/会议1-1.xml
            String xmlPath = videoFileList.get(i).getPath() + "/" + videoFileList.get(i).getMeetingName() + "/" + videoFileList.get(i).getName() + "/" + videoFileList.get(i).getName() + AppConfig.FILE_TYPE_XML;

            //拷贝水印文件
            if (FileUtil.isFileExist(SharedPreferencesUtils.getWaterMarkPath(context))) {
                Log.e(TAG, "存在-=---------");

                try {
                    FileUtil.copyFile(new File(SharedPreferencesUtils.getWaterMarkPath(context)), pngPath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Log.e(TAG, "不存在-=---------");
            }
            //拷贝批注文件
            if (i == (videoFileList.size() - 1)) {

            } else {
                try {
                    FileUtil.copyFile(new File(XmlPath), xmlPath);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            saveFiletoDB(videoFileList.get(i));
        }
        //dismissLoadDialog();
    }

    /**
     * 保存文件到数据库
     */
    private void saveFiletoDB(VideoFile videoFile) {
        Log.e(TAG, "saveFiletoDB-------");
        try {
            long size = FileUtil.getFileSize(new File(dirpath));
            VideoFile videoFile2 = new VideoFile(null, videoFile.getName(), new File(dirpath + AppConfig.FILE_TYPE_MP4).lastModified(), videoFile.getPath(), size, videoFile.getSecondname(), videoFile.getMeetingGroup(), videoFile.getMeetingName(), videoFile.getMeetingTime());
            VideoFileDaoUtils videoFileDaoUtils = new VideoFileDaoUtils(this);
            videoFileDaoUtils.insertVideoFile(videoFile2);
            updataMemory(size);
            //dismissLoadDialog();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // todo 更改内存使用情况
    private void updataMemory(long size) {
        double new_used = (double) size / 1048576;
        MemoryDaoUtils memoryDaoUtils = new MemoryDaoUtils(this);
        Memory memory = memoryDaoUtils.queryAllMemory().get(1);
        double old_uesd = (double) memory.getSize() / 1048576;
        memory.setSize(new_used + old_uesd);
        memoryDaoUtils.updateMemory(memory);
    }

    // todo 检测内存
    public boolean getSurplusSize() {
        MemoryDaoUtils memoryDaoUtils = new MemoryDaoUtils(this);
        List<Memory> list = memoryDaoUtils.queryAllMemory();

        double total = 0, used = 0;
        for (Memory memory : list) {
            if (memory.getStorageType().equals(AppConfig.MEMORY_TYPE_TOTAL_SIZE)) {
                total = memory.getSize();
            }
            if (memory.getStorageType().equals(AppConfig.MEMORY_TYPE_USED_SIZE)) {
                used = memory.getSize();
            }
        }
        double a = total - used;
        if (a < 0 || a < 5120) {
            return false;
        } else {
            return true;
        }
    }

    // 获取当前时间
    private long getCurrentTime() {
        return new Date().getTime();
    }

    //判断存数路径是否存在
    private void fileisExit(Context mContext) {
        String VideoSavePath = (String) SharedPreferencesUtils.getInstance(mContext).getDate(AppConfig.Video_SAVE_PATH, "String");
        if (FileUtil.isFileExist(VideoSavePath)) {
            FileUtil.createDir(new File(AppConfig.DESKMEDIAFILE));
            if (VideoSavePath.equals("")) {
                SharedPreferencesUtils.getInstance(mContext).putDate(AppConfig.Video_SAVE_PATH, VideoSavePath);
            }
        }
    }

    //获取存储路径
    private String getStoragePath(Context mContext) {
        String videoSavePath = SharedPreferencesUtils.getVideoSavePath(mContext);
        //会议名称
        //String meetingName = SharedPreferencesUtils.getMeetingName(mContext);
        return videoSavePath;
    }
    /**
     * 获取会议名
     * @param mContext
     * @return
     */
    private String getMeetingname(Context mContext) {
        String meetingName = SharedPreferencesUtils.getMeetingName(mContext);
        return meetingName;
    }

    /**
     * 获取会议分段后缀
     *
     * @return 1-1
     */
    private void getFileSuffix() {
        String name = i + "-" + j;
        VideoFileDaoUtils videoFileDaoUtils = new VideoFileDaoUtils(RecordService.this);
        List<VideoFile> list = videoFileDaoUtils.queryAllVideoFile();
        boolean ishas = false;
        for (VideoFile videoFile : list) {
            String s = SharedPreferencesUtils.getMeetingName(RecordService.this) + i + "-" + j;
            if (videoFile.getName().equals(s)) {
                Log.e(TAG, "haved name:" + i + "-" + j);
                ishas = true;
                break;
            }

        }
        if (ishas) {
            i++;
            getFileSuffix();
        } else {
            Log.e(TAG, "no has name:" + i + "-" + j);
        }


    }

    /**
     * 获取带有时间名称
     *
     * @return
     */
    private String getFilename(Context mContext) {
        return SharedPreferencesUtils.getMeetingName(mContext) + suffixName;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public class RecordBind extends Binder {
        public RecordService getService() {
            return RecordService.this;
        }

    }

    private void showToast(int id) {
        MyToastUtils.ShortToaseShow(RecordService.this, "");
    }

    private void showLoadDialog() {
        RxBus.getInstance().send(RxBusUtil.SHOW_LOAD_DIALOG);

    }

    private void dismissLoadDialog() {
        RxBus.getInstance().send(RxBusUtil.DISMISS_LOAD_DIALOG);

    }

    /**
     * 分段计时线程，达到分段时长执行分段
     */
    private class SubSectionThread extends Thread {
        //private long time = SharedPreferencesUtils.getSubSectionTime(RecordService.this);
        private long time = 1 * 60 * 1000;

        @Override
        public void run() {
            super.run();
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (!isStopRecord){
                stopRecord(context, true);
            }
        }
    }

    private String getMyUUID() {
        UUID uuid = UUID.randomUUID();
        String s = uuid.toString();
        return s;
    }
}
